const { autoUpdater } = require('electron-updater');
const { app, dialog, BrowserWindow } = require('electron');
const log = require('electron-log');

class AppUpdater {
  constructor() {
    // 配置日志
    log.transports.file.level = 'info';
    autoUpdater.logger = log;
    
    // 配置更新服务器
    this.setupUpdateServer();
    
    // 绑定事件
    this.bindEvents();
    
    // 更新检查间隔（毫秒）
    this.checkInterval = 30 * 60 * 1000; // 30分钟
    this.intervalId = null;
    
    // 当前更新状态
    this.updateStatus = 'idle'; // idle, checking, available, downloading, downloaded, error
    this.updateInfo = null;
  }

  setupUpdateServer() {
    // 配置更新服务器 - 使用Gitee作为更新源
    if (process.env.NODE_ENV === 'development') {
      // 开发环境配置
      autoUpdater.updateConfigPath = 'dev-app-update.yml';
      autoUpdater.forceDevUpdateConfig = true;
    } else {
      // 生产环境配置 - 使用Gitee
      autoUpdater.setFeedURL({
        provider: 'generic',
        url: 'https://bluelight.top/app-updater/study/releases',
        channel: 'latest'
      });
    }
    
    // 其他配置
    autoUpdater.autoDownload = false; // 手动控制下载
    autoUpdater.autoInstallOnAppQuit = true;
  }

  bindEvents() {
    // 检查更新
    autoUpdater.on('checking-for-update', () => {
      log.info('正在检查更新...');
      this.updateStatus = 'checking';
      this.sendUpdateStatus('checking');
    });

    // 发现可用更新
    autoUpdater.on('update-available', (info) => {
      log.info('发现可用更新:', info);
      this.updateStatus = 'available';
      this.updateInfo = info;
      this.sendUpdateStatus('available', info);
      this.showUpdateAvailableDialog(info);
    });

    // 没有可用更新
    autoUpdater.on('update-not-available', (info) => {
      log.info('当前已是最新版本');
      this.updateStatus = 'idle';
      this.sendUpdateStatus('not-available', info);
    });

    // 更新下载进度
    autoUpdater.on('download-progress', (progressObj) => {
      log.info(`下载进度: ${progressObj.percent}%`);
      this.sendUpdateStatus('downloading', progressObj);
    });

    // 更新下载完成
    autoUpdater.on('update-downloaded', (info) => {
      log.info('更新下载完成');
      this.updateStatus = 'downloaded';
      this.updateInfo = info;
      this.sendUpdateStatus('downloaded', info);
      this.showUpdateDownloadedDialog(info);
    });

    // 更新错误
    autoUpdater.on('error', (error) => {
      log.error('更新错误:', error);
      this.updateStatus = 'error';
      this.sendUpdateStatus('error', { message: error.message });
    });
  }

  // 发送更新状态到渲染进程
  sendUpdateStatus(status, data = null) {
    const allWindows = BrowserWindow.getAllWindows();
    allWindows.forEach(window => {
      window.webContents.send('update-status', {
        status,
        data,
        timestamp: Date.now()
      });
    });
  }

  // 显示更新可用对话框
  async showUpdateAvailableDialog(info) {
    const mainWindow = BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0];
    
    if (!mainWindow) return;

    const result = await dialog.showMessageBox(mainWindow, {
      type: 'info',
      title: '发现新版本',
      message: `发现新版本 v${info.version}`,
      detail: `当前版本: v${app.getVersion()}\n新版本: v${info.version}\n\n${info.releaseNotes || ''}`,
      buttons: ['立即下载', '稍后提醒', '跳过此版本'],
      defaultId: 0,
      cancelId: 1
    });

    switch (result.response) {
      case 0: // 立即下载
        this.downloadUpdate();
        break;
      case 1: // 稍后提醒
        // 30分钟后再次提醒
        setTimeout(() => {
          this.showUpdateAvailableDialog(info);
        }, 30 * 60 * 1000);
        break;
      case 2: // 跳过此版本
        // 记录跳过的版本
        global.skippedVersion = info.version;
        break;
    }
  }

  // 显示更新下载完成对话框
  async showUpdateDownloadedDialog(info) {
    const mainWindow = BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0];
    
    if (!mainWindow) return;

    const result = await dialog.showMessageBox(mainWindow, {
      type: 'info',
      title: '更新已准备就绪',
      message: '新版本已下载完成',
      detail: '重启应用以安装更新，或稍后手动重启。',
      buttons: ['立即重启', '稍后重启'],
      defaultId: 0,
      cancelId: 1
    });

    if (result.response === 0) {
      this.quitAndInstall();
    }
  }

  // 检查更新
  checkForUpdates() {
    if (this.updateStatus === 'checking' || this.updateStatus === 'downloading') {
      log.info('更新检查已在进行中');
      return;
    }

    // 检查是否跳过了某个版本
    if (global.skippedVersion) {
      log.info(`跳过版本检查: ${global.skippedVersion}`);
    }

    autoUpdater.checkForUpdates().catch(error => {
      log.error('检查更新失败:', error);
    });
  }

  // 下载更新
  downloadUpdate() {
    if (this.updateStatus !== 'available') {
      log.warn('没有可用的更新');
      return;
    }

    log.info('开始下载更新...');
    this.updateStatus = 'downloading';
    autoUpdater.downloadUpdate().catch(error => {
      log.error('下载更新失败:', error);
    });
  }

  // 退出并安装
  quitAndInstall() {
    if (this.updateStatus !== 'downloaded') {
      log.warn('更新未下载完成');
      return;
    }

    log.info('退出并安装更新...');
    autoUpdater.quitAndInstall(false, true);
  }

  // 开始定期检查
  startPeriodicCheck() {
    // 启动时立即检查一次
    setTimeout(() => {
      this.checkForUpdates();
    }, 5000); // 延迟5秒开始第一次检查

    // 设置定期检查
    this.intervalId = setInterval(() => {
      this.checkForUpdates();
    }, this.checkInterval);

    log.info(`已启动定期更新检查，间隔: ${this.checkInterval / 1000 / 60} 分钟`);
  }

  // 停止定期检查
  stopPeriodicCheck() {
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
      log.info('已停止定期更新检查');
    }
  }

  // 获取当前状态
  getStatus() {
    return {
      status: this.updateStatus,
      updateInfo: this.updateInfo,
      currentVersion: app.getVersion()
    };
  }

  // 手动检查更新（从渲染进程调用）
  async manualCheck() {
    return new Promise((resolve) => {
      const originalStatus = this.updateStatus;
      
      // 监听一次更新结果
      const cleanup = () => {
        autoUpdater.removeListener('update-available', onAvailable);
        autoUpdater.removeListener('update-not-available', onNotAvailable);
        autoUpdater.removeListener('error', onError);
      };

      const onAvailable = (info) => {
        cleanup();
        resolve({ available: true, info });
      };

      const onNotAvailable = (info) => {
        cleanup();
        resolve({ available: false, info });
      };

      const onError = (error) => {
        cleanup();
        resolve({ error: error.message });
      };

      autoUpdater.once('update-available', onAvailable);
      autoUpdater.once('update-not-available', onNotAvailable);
      autoUpdater.once('error', onError);

      this.checkForUpdates();
    });
  }
}

module.exports = AppUpdater;